// 整理出时间，物种
let year = new Set(),
  species = new Set(),
  sumCount = {};
init = () => {
  data.forEach(it => {
    let t = it.RecordDate.split("/").pop();
    year.add(t);
    species.add(it.CommonName);
    if (sumCount[t]) {
      sumCount[t] += it.individualCount;
    } else {
      sumCount[t] = it.individualCount;
    }
  });
  year = Array.from(year).filter(it => it >= 1984 && it <= 2013);
  document.querySelector(".select-year").innerHTML = Array.from(year)
    .sort((a, b) => a - b)
    .reduce((acc, cur) => {
      return cur >= 1984 && cur <= 2013
        ? acc + `<option value=${cur}>${cur}</option>`
        : acc;
    }, "");
  // document.querySelector(".select-species").innerHTML = Array.from(
  //   species
  // ).reduce((acc, cur) => acc + `<option value=${cur}>${cur}</option>`, "");
  drawSumCount("#all-count");

  document.querySelector(".select-year").addEventListener("change", yearChange);
  // document
  //   .querySelector(".select-species")
  //   .addEventListener("change", yearChange);
  webMap("year-map");
  let yearSpecies = sortSpeciesByYear(1984);
  drawSpeciesMap(yearSpecies);
  drawPie(yearSpecies);
  count(1984);
};

init();

function yearChange(e) {
  count(e.target.value);
  let yearSpecies = sortSpeciesByYear(e.target.value);
  drawSpeciesMap(yearSpecies);
  drawPie(yearSpecies);
  update();
}

//节流函数
function throttle(fn, interval) {
  let timer,
    firstTime = true;

  return function() {
    let args = arguments;
    let _me = this;

    if (firstTime) {
      fn.apply(_me, args);
      return (firstTime = false);
    }

    if (timer) {
      return false;
    }

    timer = setTimeout(function() {
      clearTimeout(timer);
      timer = null;
      fn.apply(_me, args);
    }, interval || 500);
  };
}
// 画总数图
function drawSumCount(id) {
  let initWidth = 760;
  let initHeight = 500;

  let svg = d3.select(id),
    padding = {
      left: 40,
      top: 10,
      right: 20,
      bottom: 20
    },
    width = initWidth - padding.left - padding.right,
    height = initHeight - padding.top - padding.bottom;

  svg
    .attr("width", width)
    .attr("height", height)
    .style("padding-left", padding.left)
    .style("padding-right", padding.right)
    .style("padding-top", padding.top)
    .style("padding-bottom", padding.bottom);

  let parseTime = d3.timeParse("%d/%b/%y");
  // 添加y轴坐标轴
  let yScale = d3
    .scaleLinear()
    .domain([0, d3.max(Object.values(sumCount))])
    .rangeRound([height - 30, 0]);

  let yAxis = d3.axisLeft(yScale).tickFormat(d3.format("d"));
  svg
    .append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + 0 + "," + 0 + ")")
    .call(yAxis)
    .append("text")
    .text("数量")
    .attr("transform", "translate(" + 0 + "," + (height - 15) + ")")
    .attr("fill", "black")
    .attr("font-size", 16);

  //添加x轴坐标轴

  let xScale = d3
    .scaleLinear()
    .domain([d3.min(year), d3.max(year)])
    .rangeRound([0, width]);
  let _xScale = d3
    .scaleLinear()
    .domain([0, width])
    .rangeRound([1984, 2013]);

  let xAxis = d3.axisBottom(xScale).tickFormat(d3.format("d"));
  svg
    .append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + "0 ," + (height - 30) + ")")
    .call(xAxis)
    .append("text")
    .text("年份")
    .attr("transform", "translate(" + (width - 60) + "," + 15 + ")")
    .attr("fill", "black")
    .attr("font-size", 16);
  //创建一个直线生成器
  let linePath = d3
    .line()
    .curve(d3.curveCardinal.tension(0.5))
    .x(function(d) {
      return xScale(d[0]);
    })
    .y(function(d) {
      return yScale(d[1]);
    });
  let colors = ["rgb(0, 188, 212)", "rgb(255, 64, 129)"];

  //添加路径
  let data = [
    {
      data: Object.entries(sumCount).filter(
        it => it[0] >= 1984 && it[0] <= 2013
      )
    }
  ];
  svg
    .append("g")
    .selectAll("path")
    .data(data)
    .enter()
    .append("path")
    .attr("transform", "translate(0, 0)")
    .attr("d", function(d) {
      return linePath(d.data);
    })
    .attr("fill", "none")
    .attr("stroke-width", "2px")
    .attr("stroke", function(d, i) {
      return colors[i];
    });

  let detailLine = svg
    .append("g")
    .attr("class", "line_y")
    .attr("transform", "translate(" + width + "," + 0 + ")")
    .call(
      yAxis
        .ticks(0)
        .tickSize(0)
        .tickFormat("")
    );

  //添加提示栏
  let tooltip = d3
    .select("body")
    .append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);
  //计算位置 便于吸附
  let singleStep = width / (data[0].data.length - 1);
  //这里使用节流函数，避免过多运算导致浏览器卡顿
  document.querySelector(id).onmousemove = throttle(function(e) {
    e.stopPropagation();
    let t = Math.round((e.offsetX - padding.left) / singleStep) * singleStep;
    detailLine.attr("transform", "translate(" + t + "," + 0 + ")");
    let year = _xScale(t);
    let currentHtml = [];
    data.forEach(e => {
      e.data.forEach((ev, i) => {
        if (ev[0] == year) {
          currentHtml.push(`<div>数量：${ev[1]}</div>`);
        }
      });
    });
    currentHtml.unshift(`<div>时间：${year}年</div>`);
    tooltip
      .html(currentHtml.join(""))
      .style("left", e.pageX + 20 + "px")
      .style("top", e.pageY + 20 + "px")
      .style("opacity", 1);
  }, 50);

  //隐藏显示栏
  document.onclick = function() {
    tooltip.style("opacity", 0);
  };
}
// 画地图
var map;
var mapbox;

function webMap(container) {
  let mapCoordinates = [149.154779, -35.308586];
  let mapZoom = 13;
  mapboxgl.accessToken =
    "pk.eyJ1IjoicGFuZGFjYXQiLCJhIjoiY2pmY29ubHJzMXBwbjJxb2Zrb3drYWtnYSJ9.63Ef-6kcQO-YUMi8d_4T0A";
  map = new mapboxgl.Map({
    container: container,
    style: "mapbox://styles/mapbox/streets-v10",
    center: mapCoordinates,
    zoom: mapZoom
  });
  let canvas = map.getCanvasContainer();
  let svg = d3
    .select(canvas)
    .append("svg")
    .attr("id", "mapbox");

  map.on("load", function() {
    d3
      .queue()
      .defer(
        d3.json,
        "https://raw.githubusercontent.com/codeforamerica/click_that_hood/master/public/data/canberra.geojson"
      )
      .await(drawData);
  });

  let transform = d3.geoTransform({
    point: projectPoint
  });
  let path = d3.geoPath().projection(transform);

  function projectPoint(lng, lat) {
    let point = map.project(new mapboxgl.LngLat(lng, lat));
    this.stream.point(point.x, point.y);
  }

  function drawData(err, file1data) {
    mapbox = svg
      .selectAll("path")
      .data(file1data.features)
      .enter()
      .append("path")
      .attr("d", path)
      .attr("fill", "#00bdd2")
      .attr("fill-opacity", 0.4)
      .attr("stroke", "red");
    update();
    map.on("viewreset", update);
    map.on("move", update);
    map.on("moveend", update);
  }
}

function update() {
  let d3projection = getD3();
  let transform = d3.geoTransform({
    point: projectPoint
  });
  let path = d3.geoPath().projection(transform);

  function projectPoint(lng, lat) {
    let point = map.project(new mapboxgl.LngLat(lng, lat));
    this.stream.point(point.x, point.y);
  }
  d3
    .selectAll("circle.dot")
    .attr("cx", d => {
      let coor = map.project([d.log, d.lat]);
      return coor.x;
    })
    .attr("cy", d => {
      let coor = map.project([d.log, d.lat]);
      return coor.y;
    })
    .attr("r", function(d) {
      return d.count * 2;
    });
  return mapbox.attr("d", path);
}
// 统计数量
function count(year) {
  document.querySelector(".counts").innerHTML =
    "总数量：" + Object.entries(sumCount).filter(it => it[0] == year)[0][1];
}
// 整理当前年份物种
function sortSpeciesByYear(year) {
  return data.reduce((acc, cur) => {
    if (cur.RecordDate.split("/").pop() == year) {
      let t = acc.filter(it => it.name == cur.CommonName);
      if (t.length) {
        t[0].location.push({
          log: cur.Easting_MGA,
          lat: cur.Northing_MGA,
          count: cur.individualCount
        });
      } else {
        acc.push({
          name: cur.CommonName,
          location: [
            {
              log: cur.Easting_MGA,
              lat: cur.Northing_MGA,
              count: cur.individualCount
            }
          ]
        });
      }
    }
    return acc;
  }, []);
}
// 画物种分布图
function drawSpeciesMap(data) {
  let d3projection = getD3();
  $('#mapbox').html = ''
  data.forEach((it, index) => {
    var r = Math.floor(Math.random() * 256);
    var g = Math.floor(Math.random() * 256);
    var b = Math.floor(Math.random() * 256);
    let color = `rgb(${r},${g},${b})`;
    // let color = '#333';
    it.location.forEach(item=>item.name = it.name)
    d3
      .select("#mapbox")
      .selectAll("circle.dot")
      .data(it.location)
      .enter()
      .append("circle")
      .attr("class", "dot")
      .attr("cx", d => {
        let coor = d3projection([d.log, d.lat]);
        return coor[0];
      })
      .attr("cy", d => {
        let coor = d3projection([d.log, d.lat]);
        return coor[1];
      })
      .attr("r", d => d.count * 8)
      .attr("fill", color)
      .attr("opacity", 0.7);
      var tooltip = d3
      .select("body")
      .append("div")
      .attr("class", "auto-tooltip");
  
    tooltip.append("div").attr("class", "labels");
  
    tooltip.append("div").attr("class", "counts");

    d3.selectAll('.dot').on('mousemove', function (d) {
      var event = d3.event;
      var top = d3.event.pageY;
      var left = d3.event.pageX;

      tooltip.select(".labels").html(` log: ${d.log} lat: ${d.lat}`);
      tooltip.select(".counts").html(`species:${d.name} count:${d.count}`);
      tooltip.style("display", "block")
      tooltip.style('top', top + 10 + 'px')
      tooltip.style('left', left + 10 + 'px')
      tooltip.style('opacity', 1)
    })
    .on('mouseout', function () {
      $('.auto-tooltip').hide()
    })
  });
}
// 画当年的饼图
function drawPie(data) {
  var dataset = data.slice(0, 20); // 少取点数据进行展示

  let sortdata = dataset.map(it => {
    return {
      name: it.name,
      count: it.location.reduce((acc, cur) => acc + cur.count, 0)
    };
  });
  document.querySelector("#year-pie").innerHTML = "";
  var width = $("#year-pie").outerWidth();
  var height = 500;
  var svg = d3
    .select("#year-pie")
    .append("svg")
    .attr("width", width)
    .attr("height", height);
  var radius = width / 3;
  var g = svg
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  var color = d3.scaleOrdinal([
    "#98abc5",
    "#8a89a6",
    "#7b6888",
    "#6b486b",
    "#a05d56",
    "#d0743c",
    "#ff8c00"
  ]);
  var tooltip = d3
    .select("body")
    .append("div")
    .attr("class", "auto-tooltip");

  tooltip.append("div").attr("class", "labels");

  tooltip.append("div").attr("class", "counts");
  var pie = d3
    .pie()
    .sort(null)
    .value(function(d) {
      return d.count;
    });
  var path = d3
    .arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

  var label = d3
    .arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40);

  var arc = g
    .selectAll(".arc")
    .data(pie(sortdata))
    .enter()
    .append("g")
    .attr("class", "arc");

  arc
    .append("path")
    .attr("d", path)
    .attr("fill", function(d) {
      return color(d.data.name);
    })
    .on("mousemove", function(d) {
      var top = d3.event.pageY;
      var left = d3.event.pageX;

      tooltip.select(".labels").html(`species:${d.data.name}`);
      tooltip.select(".counts").html(`count:${d.data.count}`);
      tooltip.style("display", "block")
      tooltip.style('top', top + 10 + 'px')
      tooltip.style('left', left + 10 + 'px')
      tooltip.style('opacity', 1)
    }) 
    .on('mouseout', function () {
        $('.auto-tooltip').hide()
      })

  arc
    .append("text")
    .attr("transform", function(d) {
      return "translate(" + label.centroid(d) + ")";
    })
    .attr("dy", "0.35em")
    .text(function(d) {
      return d.data.name
        .split(" ")
        .map(it => it[0])
        .join("");
    });

  //添加连接弧外文字的直线元素
  arc
    .append("line")
    .attr("stroke", "black")
    .attr("x1", function(d) {
      return path.centroid(d)[0] * 2;
    })
    .attr("y1", function(d) {
      return path.centroid(d)[1] * 2;
    })
    .attr("x2", function(d) {
      return path.centroid(d)[0] * 2.2;
    })
    .attr("y2", function(d) {
      return path.centroid(d)[1] * 2.2;
    });

  //添加弧外的文字元素
  arc
    .append("text")
    .attr("transform", function(d) {
      var x = path.centroid(d)[0] * 2.3;
      var y = path.centroid(d)[1] * 2.3;
      return "translate(" + x + "," + y + ")";
    })
    .attr("text-anchor", function(d) {
      if (
        parseFloat(
          (d.startAngle + (d.endAngle - d.startAngle) / 2).toFixed(2)
        ) <= parseFloat(Math.PI.toFixed(2))
      ) {
        //判断扇形中线所在的弧度是否超过半圆
        return "start";
      } else {
        return "end";
      }
    })
    .text(function(d) {
      return d.data.name;
    });
}
// d3 投影
function getD3() {
  var center = map.getCenter();
  var zoom = map.getZoom();
  var scale = 512 * 0.5 / Math.PI * Math.pow(2, zoom);

  var d3projection = d3
    .geoMercator()
    .center([center.lng, center.lat])
    .translate([300, 250])
    .scale(scale);

  return d3projection;
}
